<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <h2>watch侦听器</h2>

    <input type="text" v-model="textValue" />

    <p>count: {{ count }}</p>
    <button @click="count++">count++</button>


    <p id="p">obj: {{ obj }}</p>
    <button @click="obj.age = 50">btn</button>


    <p>num: {{ num }}</p>
    <button @click="num = num * 2">num * 2</button>
    <button @click="start">开启对num的监听</button>
    <button @click="stop">关闭对num的监听</button>
  </div>

  <script src="../vue3.js"></script>
  <script>
    const {createApp} = Vue;

    let fn;

    createApp({
      data() {
        return {
          textValue: "",
          count: 1,
          obj: {
            name: "junge",
            age: 40
          },
          num: 10
        }
      },
      // 侦听器选项
      watch: {
        // watch里面的函数的名字要和data的变量名字一样
        // watch里面的函数，会在对应的这个变量发生改变的时候触发

        // watch函数都可以接收两个参数，分别是改变后的值和改变前的值
        // watch不需要return
        // 并且可以在这里去做异步操作(数据请求和定时器)
        textValue(val, oldVal) {
          setTimeout(() => {
            console.log("textValue改变了", val, oldVal);
          }, 1000)
        },

        count(val) {
          console.log("count的新值是" + val);
        },

        // 复杂类型数据，如果地址没有发生改变，默认是监听不到变化的
        // 1. 可以通过加引号的方式，监听对象下面的属性
        // "obj.age"() {
        //   console.log("age改变了");
        // }
        // 2. 强行深度监听
        // 需要将函数写成对象的形式，加上handler函数，再加deep: true,
        obj: {
          handler() {
            // console.log("obj改变了");
            console.log(document.querySelector("#p").innerHTML);
          },
          deep: true,
          // 强制立即执行回调
          // 加上immediate: true，表示handler函数会在进入页面就触发一次
          // immediate: true,
          // once: true表示一次性侦听
          // once: true
          // 默认情况下，watch函数的执行时机类似于beforeUpdate
          // 加上flush: 'post'，就相当于将函数的执行时机类似于updated
          flush: 'post'
        }
      },

      // updated() {
      //   console.log(this.count, this.textValue);
      // }
      methods: {
        // this.$watch可以很方便的开启和关闭监听，vue3新增的
        start() {
          // 开启监听
          fn = this.$watch('num', (val) => {
            console.log("num改变了" + val);
          })
        },
        stop() {
          // 停止监听
          fn();
        }
      }
    }).mount("#app");
  </script>
</body>
</html>